﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;

namespace DAH_TD_
{
    public class Tower
    {
        int type;
            public int getType() { return this.type; }

        private ContentManager t_content;
        public Texture2D towerTexture;
        public String texturePath;

        TimeSpan attackSpeedTimeSpan;
        TimeSpan previousAttack;

        public Rectangle boundarie;
        Rectangle rangeRectangle;

        float damage;
            public float getDamage() { return this.attackSpeed; }
        float piercingDamageInPercent;
            public float getPiercingDamage() { return this.piercingDamageInPercent; }
        float attackSpeed;
            public float getAttackSpeed() { return this.attackSpeed; }
        float range;
            public float getRange() { return this.range; }
        float costs;
            public float getCosts() { return this.costs; }
        TileMap map;
        Vector2 position;
            public Vector2 getPosition() { return this.position; }

        public Tower(TileMap map, int type, Vector2 position)
        {
            this.map = map;
            this.position = position;
            this.boundarie = new Rectangle((int)position.X, (int)position.Y, (int)map.getTileWidth(), (int)map.getTileHeight());
            this.boundarie.X = (int)getPos().X * (int)map.getTileWidth();
            this.boundarie.Y = (int)getPos().Y * (int)map.getTileHeight();

            // TowerFolder
            String towerPath = "Towers/0" + type + ".tower";
            if (type > 9) { towerPath = "Towers/" + type + ".tower"; }

            // TOWER EINLESEN
            System.IO.StreamReader file;
            String currentDirectory = GetProjectPath();

            String combinedPath = Path.Combine(currentDirectory, towerPath);

            // Tower-Datei öffnen
            file = new System.IO.StreamReader(combinedPath);

            // Typ
            file.ReadLine();
            this.type = Convert.ToInt32(file.ReadLine());
            // Textur
            file.ReadLine();
            this.texturePath = Convert.ToString(file.ReadLine());
            // Kosten
            file.ReadLine();
            this.costs = Convert.ToInt32(file.ReadLine());
            // Schaden
            file.ReadLine();
            this.damage = Convert.ToInt32(file.ReadLine());
            // Speed
            file.ReadLine();
            this.attackSpeed = (float)(Convert.ToInt32(file.ReadLine()) / 100);
            // Durchdringung
            file.ReadLine();
            this.piercingDamageInPercent = (float)(Convert.ToInt32(file.ReadLine())/100);
            // Reichweite
            file.ReadLine();
            this.range = (float)(Convert.ToInt32(file.ReadLine())/100);
       
            file.Close();
            
            this.attackSpeedTimeSpan = TimeSpan.FromSeconds((double)this.attackSpeed);
            this.rangeRectangle = new Rectangle(this.boundarie.X - ((int)this.range * this.map.getTileWidth()), this.boundarie.Y - ((int)this.range * this.map.getTileHeight()), (2 * (int)this.range * this.map.getTileWidth()) + this.map.getTileWidth(), (2 * (int)this.range * this.map.getTileHeight()) + this.map.getTileHeight());
        }

        public Tower(int type)
        {
            this.type = type;

            // TowerFolder
            String towerPath = "Towers/0" + type + ".tower";
            if (type > 9) { towerPath = "Towers/" + type + ".tower"; }

            // TOWER EINLESEN
            System.IO.StreamReader file;
            String currentDirectory = GetProjectPath();

            String combinedPath = Path.Combine(currentDirectory, towerPath);

            // Tower-Datei öffnen
            file = new System.IO.StreamReader(combinedPath);

            // Typ
            file.ReadLine();
            this.type = Convert.ToInt32(file.ReadLine());
            // Textur
            file.ReadLine();
            this.texturePath = Convert.ToString(file.ReadLine());
            // Kosten
            file.ReadLine();
            this.costs = Convert.ToInt32(file.ReadLine());
            // Schaden
            file.ReadLine();
            this.damage = Convert.ToInt32(file.ReadLine());
            // Speed
            file.ReadLine();
            this.attackSpeed = (float)(Convert.ToInt32(file.ReadLine()) / 100);
            // Durchdringung
            file.ReadLine();
            this.piercingDamageInPercent = (float)(Convert.ToInt32(file.ReadLine()) / 100);
            // Reichweite
            file.ReadLine();
            this.range = (float)(Convert.ToInt32(file.ReadLine()) / 100);

            file.Close();
        }

        public Tower(){}

        public bool Initialize(ContentManager content)
        {
            this.t_content = content;
            return true;
        }

        public void LoadContent()
        {
            towerTexture = t_content.Load<Texture2D>(texturePath);
        }

        public void Update()
        {

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(towerTexture, boundarie, Color.White);        
        }

        public Vector2 getPos()
        {
            Vector2 actualTile;
            int b = map.getTileWidth();
            float xTile = position.X / b;
            int xPos = (int)xTile;
            actualTile.X = xPos;
            // in y-Richtung: 
            int h = map.getTileHeight();
            float yTile = position.Y / h;
            int yPos = (int)yTile;
            actualTile.Y = yPos;

            return actualTile;
        }

        public bool checkIfAttack(GameTime gt) {
            if (gt.TotalGameTime - previousAttack > attackSpeedTimeSpan)
            {
                previousAttack = gt.TotalGameTime;
                return true;
            }
            else { return false; }
        }

        public void attackEnemy(Enemy enemyToAttack) {
            enemyToAttack.setHp(enemyToAttack.getHp() - this.damage);
        }

        public List<Enemy> enemiesInTowerRange(List<Enemy> enemies)
        {
            List<Enemy> enemiesInRange = new List<Enemy>();
            // für jeden Turm wird die Position bestimmt und anhand der Reichweite (in Kacheln) mögliche Gegener ermittelt
            for (int i = 0; i < enemies.Count; i++)
            {
                if (this.rangeRectangle.Intersects(enemies[i].getBoundarie()))
                {
                    enemiesInRange.Add(enemies[i]);
                }
            }
            return enemiesInRange;
        }

        public bool ifEnemiesInTowerRange(List<Enemy> enemies)
        {
            List<Enemy> enemiesInRange = new List<Enemy>();
            for (int i = 0; i < enemies.Count; i++ )
            {
                if (this.rangeRectangle.Intersects(enemies[i].getBoundarie())){
                    enemiesInRange.Add(enemies[i]);
                }
            }
            
            
            if (enemiesInRange.Count >= 1) {return true;}
            else {return false;}
        }

        //Dateipfad finden
        internal static string GetProjectPath()
        {
            // Ergebnis: Debug- oder Release-Ordner im Projektordner.
            string projectPath = Environment.CurrentDirectory;
            // Mit jedem Durchlauf geht es im Verzeichnisbaum eine Stufe höher.
            for (int i = 0; i <= 5; i++)
            {
                projectPath = System.IO.Path.GetDirectoryName(projectPath);
            }
            return projectPath + @"\";
        }

    }
}
